package com.punai.customer.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.punai.common.core.domain.TreeBo;
import com.punai.common.exception.ServiceException;
import com.punai.common.utils.StringUtils;
import com.punai.customer.domain.CusMaterialChapter;
import com.punai.customer.domain.contants.CusConstants;
import com.punai.customer.mapper.CusLinkFeatureMapper;
import com.punai.customer.mapper.CusLinkMaterialStaCusMapper;
import com.punai.customer.mapper.CusMaterialChapterMapper;
import com.punai.customer.mapper.CusMaterialItemMapper;
import com.punai.customer.service.ICusMaterialChapterService;
import com.punai.standard.domain.StaClChapter;
import com.punai.standard.mapper.StaClChapterMapper;
import com.punai.standard.mapper.StaVersionMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 材料章节Service业务层处理
 *
 * @author zhx
 * @date 2022-12-04
 */
@Service
public class CusMaterialChapterServiceImpl extends ServiceImpl<CusMaterialChapterMapper,CusMaterialChapter> implements ICusMaterialChapterService
{
    @Autowired
    private CusMaterialChapterMapper cusMaterialChapterMapper;
    @Autowired
    private CusMaterialItemMapper cusMaterialItemMapper;
    @Autowired
    private CusLinkMaterialStaCusMapper staCusMapper;
    @Autowired
    private StaVersionMapper staVersionMapper;
    @Autowired
    private StaClChapterMapper staClChapterMapper;
    @Autowired
    private CusLinkFeatureMapper cusLinkFeatureMapper;

    /**
     * 查询材料章节
     *
     * @param id 材料章节主键
     * @return 材料章节
     */
    @Override
    public CusMaterialChapter selectCusMaterialChapterById(String id,Long companyId)
    {
        return this.getById(id,companyId);
    }

    /**
     * 查询材料章节列表
     *
     * @param cusMaterialChapter 材料章节
     * @return 材料章节
     */
    @Override
    public List<CusMaterialChapter> selectCusMaterialChapterList(CusMaterialChapter cusMaterialChapter)
    {
        return cusMaterialChapterMapper.selectCusMaterialChapterList(cusMaterialChapter);
    }

    /**
     * 新增材料章节
     *
     * @param cusMaterialChapter 材料章节
     * @return 结果
     */
    @Override
    @Transactional
    public int insertCusMaterialChapter(CusMaterialChapter cusMaterialChapter)
    {
        String pid = cusMaterialChapter.getPid();
        if (StrUtil.isEmpty(pid)) {
            pid = "0";
            cusMaterialChapter.setPid("0");
            cusMaterialChapter.setPids("0");
        } else {
            CusMaterialChapter chapter = getById(pid, cusMaterialChapter.getCompanyId());
            String pids = chapter.getPids();
            if (StrUtil.isEmpty(pids)) {
                pids = "";
            }
            cusMaterialChapter.setPids(pids + "," + chapter.getId());
        }
        Integer maxOrderNum = maxOrderNum(pid,cusMaterialChapter.getCompanyId());
        cusMaterialChapter.setOrderNum(maxOrderNum + 1);
        return cusMaterialChapterMapper.insert(cusMaterialChapter);
    }

    private Integer maxOrderNum(String pid,Long companyId) {
        return cusMaterialChapterMapper.selectMaxOrderNum(pid, companyId);
    }

    private CusMaterialChapter getById(String id, Long companyId) {
        LambdaQueryWrapper<CusMaterialChapter> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CusMaterialChapter::getId,id);
        queryWrapper.eq(CusMaterialChapter::getCompanyId,companyId);
        return cusMaterialChapterMapper.selectOne(queryWrapper);
    }

    /**
     * 修改材料章节
     *
     * @param chapter 材料章节
     * @return 结果
     */
    @Override
    @Transactional
    public int updateCusMaterialChapter(CusMaterialChapter chapter) {
        LambdaQueryWrapper<CusMaterialChapter> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CusMaterialChapter::getCompanyId, chapter.getCompanyId());
        queryWrapper.eq(CusMaterialChapter::getId, chapter.getId());
        return cusMaterialChapterMapper.update(chapter,queryWrapper);
    }

    /**
     * 删除材料章节信息
     *
     * @param id 材料章节主键
     * @return 结果
     */
    @Override
    @Transactional
    public int deleteCusMaterialChapterById(String id,Long companyId,String shape) {
        List<String> childrenIds = cusMaterialChapterMapper.selectChildrenIdById(id, companyId);
        childrenIds.add(id);
        if (StringUtils.equals(shape, "Y")) {
            List<String> itemIds = cusMaterialItemMapper.selectIdsByChapterIds(companyId, childrenIds);
            if (CollUtil.isNotEmpty(itemIds)) {
                staCusMapper.deleteLinkByCusId(itemIds, companyId);
                cusMaterialItemMapper.deleteCusMaterialItemByIds(itemIds, companyId);
                cusLinkFeatureMapper.deleteByItemIds(companyId,itemIds);
            }
        } else {
            cusMaterialItemMapper.updateChapterIdIsZero(childrenIds, companyId, CusConstants.CHAPTER_ID_NULL);
        }
        cusMaterialChapterMapper.deleteCusMaterialChapterByIds(childrenIds, companyId);
        return 200;
    }

    @Override
    @Transactional
    public void moveTree(String type, String id, String dropId,Long companyId) {
        if (!StrUtil.containsAny(type,"inner","before","after")) {
            throw new ServiceException("参数错误!");
        }
        CusMaterialChapter chapter = getById(dropId, companyId);
        CusMaterialChapter moveChapter = getById(id, companyId);

        // 处理 移动数据之后的数据
        String targetPid = chapter.getPid();
        String movePid = moveChapter.getPid();
        boolean isProcessLastOrderNum = false;
        // 切换层级了
        boolean changeParent = false;
        if (!StrUtil.equals(targetPid,movePid)) {
            changeParent = true;
            // 发生了pid替换
            // 将之后的章节的 orderNum - 1
            orderNumProcess(companyId,movePid,moveChapter.getOrderNum(),-1);
            isProcessLastOrderNum = true;
            chapter = getById(dropId, companyId);
            moveChapter = getById(id, companyId);
        }
        if ( StringUtils.equals(type,"inner")) {
            // 处理后面的节点
            if (!isProcessLastOrderNum) {
                orderNumProcess(companyId,movePid,moveChapter.getOrderNum(),-1);
                chapter = getById(dropId, companyId);
                moveChapter = getById(id, companyId);
            }
            // 放到了谁的里面 成为了谁的孩子 会成为最后一个
            // 处理序号
            Integer targetOrderNum = maxOrderNum(chapter.getId(),companyId);
            moveChapter.setOrderNum(targetOrderNum + 1);
            String newPids = StrUtil.emptyToDefault(chapter.getPids(),"0") + "," + chapter.getId();
            String oldPids = moveChapter.getPids();
            moveChapter.setPid(chapter.getId());
            moveChapter.setPids(newPids);
            // 处理子节点的pid
            updateChapterChildrenPids(moveChapter.getId(),companyId,newPids,oldPids);
        } else if( StringUtils.equals(type,"before")) {
            if (changeParent) {
                // 在谁之前
                Integer targetOrderNum = chapter.getOrderNum();
                // 处理目标之后的序号
                orderNumProcess(companyId,targetPid,targetOrderNum,+1);
                // 处理目标序号
                chapter.setOrderNum(targetOrderNum + 1);
                // 把目标序号赋给插入进来的对象
                moveChapter.setOrderNum(targetOrderNum);
            } else {
                // 同层
                Integer targetOrderNum = chapter.getOrderNum();
                Integer orderNum = moveChapter.getOrderNum();
                int num = 1;
                // 目标序号大于 当前序号
                // 下移   中间需要 -1
                // 自身 = 目标序号 - 1

                // 如果目标序号 小于当前序号
                // 上移   中间需要 +1
                // 自身 = 目标序号
                // 目标 = 目标序号 + 1
                if (targetOrderNum > orderNum) {
                    num = -1;
                }
                if (Math.abs(targetOrderNum-orderNum) == 1) {
                    chapter.setOrderNum(orderNum);
                    moveChapter.setOrderNum(targetOrderNum);
                } else {
                    orderNumProcessStartEnd(companyId,targetPid,Math.min(targetOrderNum,orderNum),Math.max(targetOrderNum,orderNum),num);
                    if (num == 1) {
                        // 目标序号 小于 当前当前 上移
                        // 自身 = 目标序号
                        moveChapter.setOrderNum(targetOrderNum);
                        // 目标
                        chapter.setOrderNum(targetOrderNum + 1);
                    } else {
                        // 目标序号 大于 当前当前 下移
                        // 自身 = 目标序号 - 1
                        moveChapter.setOrderNum(targetOrderNum - 1);
                    }
                }
            }
        } else if( StringUtils.equals(type,"after")) {
            if (changeParent) {
                // 在谁之后
                Integer targetOrderNum = chapter.getOrderNum();
                // 处理目标之后的序号
                orderNumProcess(companyId,targetPid,targetOrderNum,+1);
                // 把目标序号赋给插入进来的对象
                moveChapter.setOrderNum(targetOrderNum + 1);
            } else {
                Integer targetOrderNum = chapter.getOrderNum();
                Integer orderNum = moveChapter.getOrderNum();
                // 之后

                // 目标序号大于 当前序号
                // 下移   中间需要 -1
                // 自身 = 目标序号
                // 目标 = 目标序号 - 1

                // 如果目标序号 小于当前序号
                // 上移   中间需要 +1
                // 自身 = 目标序号 + 1
                // 目标 = 目标序号

                int num = 1;
                if (targetOrderNum > orderNum) {
                    num = -1;
                }
                if (Math.abs(targetOrderNum-orderNum) == 1) {
                    chapter.setOrderNum(orderNum);
                    moveChapter.setOrderNum(targetOrderNum);
                } else {
                    orderNumProcessStartEnd(companyId,targetPid,Math.min(targetOrderNum,orderNum),Math.max(targetOrderNum,orderNum),num);
                    if (num == 1) {
                        // 如果目标序号 小于当前序号
                        // 自身 = 目标序号 + 1
                        moveChapter.setOrderNum(targetOrderNum + 1);
                    } else {
                        //  目标序号大于 当前序号
                        // 自身 = 目标序号
                        moveChapter.setOrderNum(targetOrderNum);
                        // 目标 = 目标序号 - 1
                        chapter.setOrderNum(targetOrderNum - 1);
                    }
                }
            }
        }
        if (changeParent) {
            if (!StrUtil.equals(type,"inner")) {
                // 处理pid pids
                String newPids = StrUtil.emptyToDefault(chapter.getPids(),"");
                String oldPids = moveChapter.getPids();
                moveChapter.setPid(chapter.getPid());
                moveChapter.setPids(newPids);
                updateChapterChildrenPids(moveChapter.getId(),companyId,newPids,oldPids);
            }
        }
        updateCusMaterialChapter(chapter);
        updateCusMaterialChapter(moveChapter);
    }

    private void orderNumProcess(Long companyId,String pid,Integer orderNum,Integer num) {
        if (num == 1 || num == -1) {
            cusMaterialChapterMapper.orderNumProcess(companyId,pid,orderNum,num);
        } else {
            throw new ServiceException("序号参数错误");
        }
    }

    private void orderNumProcessStartEnd(Long companyId,String pid,Integer startNum,Integer endNum,Integer num) {
        if (num == 1 || num == -1) {
            cusMaterialChapterMapper.orderNumProcessStartEnd(companyId,pid,startNum,endNum,num);
        } else {
            throw new ServiceException("序号参数错误");
        }
    }

    private void updateChapterChildrenPids(String id, Long companyId, String newPids, String oldPids) {
        List<CusMaterialChapter> children = cusMaterialChapterMapper.selectChildrenById(id, companyId);
        if (CollUtil.isNotEmpty(children)) {
            for (CusMaterialChapter child : children) {
                child.setPids(child.getPids().replaceFirst(oldPids,newPids));
            }
            cusMaterialChapterMapper.updateChildrenPids(children,companyId);
        }
    }

    @Override
    public List<TreeBo> treeData(Long companyId) {
        List<TreeBo> result = new ArrayList<>();
        LambdaQueryWrapper<CusMaterialChapter> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(CusMaterialChapter::getCompanyId,companyId);
        List<CusMaterialChapter> chapters = cusMaterialChapterMapper.selectList(queryWrapper);
        if (CollUtil.isEmpty(chapters)) {
            return result;
        }
        result = TreeBo.convert(chapters);
        return result;
    }

    @Override
    public StaClChapter getStaClChapterById(String id, Long companyId) {
        String newestId = staVersionMapper.getNewestId(companyId, CusConstants.CL_TYPE,null);
        return staClChapterMapper.selectStaClChapterById(newestId, id);
    }

}
